import PySimpleGUI as sg
import hashlib
import threading
import os
import pyperclip
from __version__ import __version__

CHUNK_SIZE = 65536


def calculate_md5(file_path, window):
    try:
        file_size = os.path.getsize(file_path)
        hash_md5 = hashlib.md5()
        read_size = 0
        with open(file_path, "rb") as f:
            for chunk in iter(lambda: f.read(CHUNK_SIZE), b""):
                hash_md5.update(chunk)
                read_size += len(chunk)
                window.write_event_value('-PROGRESS-', (read_size, file_size))

        md5 = hash_md5.hexdigest()

        pyperclip.copy(md5)  # 自动复制MD5值到剪贴板
        return md5
    except FileNotFoundError:
        return "File not found."
    except Exception as e:
        return str(e)


# 线程执行函数
def thread_calculate_md5(window, file_path, progress_bar):
    md5_value = calculate_md5(file_path, window)
    window.write_event_value('-THREAD-', md5_value)  # 使用事件通知主线程


def main():

    global progress_bar
    font_yh = ('微软雅黑', 10)
    font_cs = ('Consolas', 11)

    layout = [
        [
            sg.FileBrowse('选择文件', key='FILE', font=font_yh, size=(8, 1)),
            sg.Input(size=(60, 1), enable_events=True, key='FILE-PATH')
        ],
        [
            sg.Button('计算 MD5', font=font_yh, size=(8, 1)),
            sg.Text('', size=(45, 1), key='MD5', enable_events=True, font=font_cs, tooltip='点我即可复制'),
            sg.Text('复制文本', size=(15, 1), key='COPY', enable_events=True, font=font_yh)],
        [
            sg.Column([
                [sg.ProgressBar(1000, orientation='h', size=(20, 20), key='PROGRESS_BAR', expand_x=True)]
            ], visible=False, key='PROGRESS_COL', expand_x=True)]
    ]

    window = sg.Window(f'MD5 小工具 v{__version__}', layout, size=(600, 120))

    # 事件循环
    while True:
        event, values = window.read()

        if event == sg.WIN_CLOSED:
            break

        if event == '计算 MD5':
            file_path = values['FILE']
            if file_path:
                window['PROGRESS_COL'].update(visible=True)  # 显示进度条列
                progress_bar = window['PROGRESS_BAR']
                progress_bar.UpdateBar(0, 1000)  # 重置进度条
                threading.Thread(target=thread_calculate_md5, args=(window, file_path, progress_bar), daemon=True).start()
            else:
                sg.popup('请先选择要计算的文件！', title='', font=font_yh)

        if event == '-PROGRESS-':  # 进度条事件
            read_size, file_size = values[event]
            progress_bar.UpdateBar(read_size, file_size)

        if event == '-THREAD-':  # 线程事件
            md5_value = values[event]
            window['MD5'].update(md5_value)
            window['PROGRESS_COL'].update(visible=False)  # 隐藏进度条列

        if event == 'MD5' or event == 'COPY':
            md5_value = window['MD5'].get()
            pyperclip.copy(md5_value)
            if md5_value:
                sg.popup('已成功复制MD5值！', no_titlebar=True, font=font_yh, auto_close=True, auto_close_duration=2)

        if event == 'FILE-PATH':
            window['MD5'].update(value='')

    window.close()


if __name__ == '__main__':
    main()